﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using Rerun.Domain;
using Rerun.Exceptions;
using Rerun.Util;

namespace Rerun.Services {

    /// <summary>
    /// 
    /// </summary>
    public class ProcessService {
        private static EventLog eventlog = new EventLog();

        /// <summary>
        /// 
        /// </summary>
        /// <exception cref="ProcessException"></exception>
        public ProcessService() {
            try {
                EvaluateProcesses();
            } catch(Exception e) {
                throw new ProcessException(string.Format("There was a problem trying to initially evaluate the processes: {0}", e.Message));
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <exception cref="ProcessException"></exception>
        public void EvaluateProcesses() {
            try {
                foreach(var processInfo in ConfigurationService.ProcessInfoList) {
                    FileInfo fileInfo = new FileInfo(processInfo.ExecutableName);

                    List<Process> processes = ProcessUtil.GetProcessesByName(fileInfo.Name);

                    if(processes.Count == 0) {
                        processInfo.NumberOfStarts += 1;
                        LoggingService.WriteEventLogEntry(string.Format("The following process is not running and will be started: {0}", processInfo.ExecutableName), EventLogEntryType.Information);

                        RecoverProcess(processInfo);
                    }
                }
            } catch(Exception e) {
                throw new ProcessException(string.Format("There was a problem evaluating the processes: {0}", e.Message));
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="processInfo"></param>
        /// <returns></returns>
        /// <exception cref="ProcessException"></exception>
        private bool RecoverProcess(ProcessInfo processInfo) {
            Process process = new Process();

            try {
                process.StartInfo.FileName = processInfo.ExecutableName;

                if(ProcessUtil.StartProcess(process)) {
                    processInfo.JustStarted = true;
                }
            } catch(Exception e) {
                throw new ProcessException(string.Format("There was a problem trying to start a process (process name: {0}): {1}", processInfo.ExecutableName, e.Message));
            } finally {
                process.Dispose();
            }

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <exception cref="ProcessException"></exception>
        public void NotifyUser() {
            try {
                if(ConfigurationService.ShowUserNotifications) {
                    foreach(var processInfo in ConfigurationService.ProcessInfoList) {
                        if((processInfo.NumberOfStarts > ConfigurationService.ApplicationRestartWarningThreshhold) && (processInfo.JustStarted)) {
                            UserNotificationService.ShowSimpleQuestion(string.Format("The application '{0}' has been started {1} time(s). Are we really going to keep playing this game?", processInfo.ExecutableName, processInfo.NumberOfStarts), "Are we really going to keep playing this game?");
                            LoggingService.WriteEventLogEntry(string.Format("Rerun has warned the user after restarting '{0}' {1} time(s)", processInfo.ExecutableName, processInfo.NumberOfStarts), EventLogEntryType.Information);
                        }
                    }
                }
            } catch(NotificationException ne) {
                throw new ProcessException(ne.Message);
            }
        }
    }
}